package com.example.statemachine.machine.base;

import com.example.statemachine.machine.enums.EnumFsmEvent;
import com.example.statemachine.machine.enums.EnumFsmStatus;
import com.example.statemachine.machine.state.*;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @author jianwei.wang
 * @version v1.0
 * @date 2019/5/9 13:51
 * 状态机实现类
 **/
public class FsmMachineService<T> implements FsmMachine {

    private static final Map<EnumFsmStatus, FsmState> stateMap = new HashMap<>(10);

    /**列举目前存在的所有状态体*/
    private TempStorageStateService tempStorageStateService;
    private IsReviewStateService isReviewStateService;
    private ReviewedStateService reviewedStateService;
    private AntiReviewStateService antiReviewStateService;
    private CancelStateService cancelStateService;

    public FsmMachineService(TempStorageStateService tempStorageStateService, IsReviewStateService isReviewStateService, ReviewedStateService reviewedStateService, AntiReviewStateService antiReviewStateService, CancelStateService cancelStateService) {
        this.tempStorageStateService = tempStorageStateService;
        this.isReviewStateService = isReviewStateService;
        this.reviewedStateService = reviewedStateService;
        this.antiReviewStateService = antiReviewStateService;
        this.cancelStateService = cancelStateService;
    }

    @Override
    @PostConstruct
    public void initMachine() {
        stateMap.put(EnumFsmStatus.TEMP_STORAGE, tempStorageStateService);
        stateMap.put(EnumFsmStatus.IS_REVIEW, isReviewStateService);
        stateMap.put(EnumFsmStatus.REVIEWED, reviewedStateService);
        stateMap.put(EnumFsmStatus.ANTI_REVIEWED, antiReviewStateService);
        stateMap.put(EnumFsmStatus.CANCELED, cancelStateService);
    }

    @Override
    public FsmState getState(int status) {
        EnumFsmStatus fsmStatus = EnumFsmStatus.getFsmStatus(status);
        return stateMap.get(fsmStatus);
    }

    @Override
    public FsmResBody execute(int event, int status) {
        EnumFsmEvent fsmEvent = EnumFsmEvent.getFsmEvent(event);
        FsmState state = this.getState(status);
        return state.execute(fsmEvent);
    }

    public FsmResBody execute(int event, int status, T t) {
        EnumFsmEvent fsmEvent = EnumFsmEvent.getFsmEvent(event);
        FsmState state = this.getState(status);
        state.setT(t);
        return state.execute(fsmEvent);
    }
}
